<template>
  <div class="wrapper">
    <div class="search">
      <Form layout="inline" :model="formState" @finish="handleFinish">
        <Form.Item label="菜单名称">
          <Input v-model:value="formState.name" placeholder="菜单名称" allowClear>
            <template #prefix><UserOutlined style="color: rgb(0 0 0 / 25%)" /></template>
          </Input>
        </Form.Item>
        <Form.Item label="状态">
          <Select
            v-model:value="formState.active"
            style="width: 150px"
            placeholder="请选择状态"
            allowClear
            :options="[
              { label: '启用', value: '1' },
              { label: '停用', value: '0' },
            ]"
          />
        </Form.Item>
        <Form.Item>
          <Button type="primary" html-type="submit" @click="findList"> 搜索 </Button>
        </Form.Item>
        <Form.Item>
          <Button @click="reset"> 重置 </Button>
        </Form.Item>
      </Form>
    </div>
    <div class="tableWrapeer">
      <div class="btnUnion">
        <Button type="primary" @click="addMenu"> 新增菜单 </Button>
      </div>
      <Table
        :columns="columns"
        :data-source="dataSource"
        :row-selection="rowSelection"
        :pagination="false"
      >
        <template #bodyCell="{ column, text, record }">
          <template v-if="column.key === 'action'">
            <span style="display: none">{{ text }}</span>
            <span>
              <Button size="small" type="primary" @click="editMenu(record.id)">
                <template #icon>
                  <EditOutlined />
                </template>
              </Button>
              &nbsp;&nbsp;
              <Popconfirm
                title="确认删除该菜单吗?"
                ok-text="确定"
                cancel-text="取消"
                disabled
                @confirm="delMenu(record.id)"
              >
                <Button size="small" type="danger" disabled>
                  <template #icon>
                    <DeleteOutlined />
                  </template>
                </Button>
              </Popconfirm>
            </span>
          </template>
        </template>
      </Table>
    </div>
    <!-- 新增编辑抽屉 -->
    <Drawer
      v-model:visible="visible"
      width="40%"
      class="custom-class"
      style="color: red"
      :title="drawTit"
      placement="right"
      @after-visible-change="afterVisibleChange"
    >
      <Form :model="formObj">
        <div class="formFlex">
          <Form.Item label="菜单名称">
            <Input v-model:value="formObj.name" placeholder="菜单名称">
              <template #prefix><UserOutlined style="color: rgb(0 0 0 / 25%)" /></template>
            </Input>
          </Form.Item>
          <Form.Item label="菜单地址">
            <Input v-model:value="formObj.path" placeholder="菜单地址">
              <template #prefix><UserOutlined style="color: rgb(0 0 0 / 25%)" /></template>
            </Input>
          </Form.Item>
        </div>
        <div class="formFlex">
          <Form.Item label="重定向">
            <Input v-model:value="formObj.redirect" placeholder="重定向">
              <template #prefix><UserOutlined style="color: rgb(0 0 0 / 25%)" /></template>
            </Input>
          </Form.Item>
          <Form.Item label="元数据">
            <Input v-model:value="formObj.meta" placeholder="元数据">
              <template #prefix><UserOutlined style="color: rgb(0 0 0 / 25%)" /></template>
            </Input>
          </Form.Item>
        </div>
        <div class="formFlex">
          <Form.Item label="上级菜单">
            <TreeSelect
              v-model:value="formObj.parentMenu"
              show-search
              style="width: 200px"
              :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
              placeholder="Please select"
              allow-clear
              tree-default-expand-all
              :tree-data="formTreeSource"
              :field-names="{
                children: 'children',
                value: 'id',
                label: 'name',
              }"
              tree-node-filter-prop="name"
            />
          </Form.Item>
          <Form.Item label="状态">
            <Select
              v-model:value="formObj.active"
              style="width: 150px"
              placeholder="请选择状态"
              allowClear
              :options="[
                { label: '启用', value: 1 },
                { label: '停用', value: 0 },
              ]"
            />
          </Form.Item>
        </div>
        <Form.Item :wrapper-col="{ span: 14, offset: 8 }">
          <Button @click="handlerClose"> 取消 </Button>
          <Button @click="btnOk" type="primary" style="margin-left: 20px"> 确认 </Button>
        </Form.Item>
      </Form>
    </Drawer>
  </div>
</template>
<script setup lang="ts">
  import { onMounted, reactive, ref } from 'vue';
  import { columns } from './menu.data';
  import { createMenu, deleteMenu, getMenuDetail, getMenuList, updateMenu } from '/@/api/sys/menu';
  import { EditOutlined, DeleteOutlined } from '@ant-design/icons-vue';
  import {
    Table,
    Form,
    Input,
    Button,
    Select,
    Drawer,
    TreeSelect,
    message,
    Popconfirm,
  } from 'ant-design-vue';

  onMounted(() => {
    findList();
  });

  const dataSource = ref([]);
  const drawTit = ref('新建菜单');
  const formState = reactive({});
  const formObj = ref({});
  const formTreeSource = ref([]);

  const convertTreeMenuData = (data, judgeId) => {
    const menus = [];
    data.filter((menu) => {
      if (menu.pid === judgeId) {
        menus.push({
          ...menu,
          key: menu.id,
          children: convertTreeMenuData(data, menu.id),
        });
      }
    });
    return menus;
  };
  // 查询
  const findList = async () => {
    const data = await getMenuList({ ...formState });
    if (data.length === 1) {
      /**
       * 只针针对于查询时的临时处理，查询的目标为子节点目录
       * 临时将其pid指向根节点，但是只是在表格里进行假展示
       * 编辑时还是真实的上级节点对应关联
       */
      data[0].pid = 0;
    }
    // 将其转化为树形结构
    dataSource.value = convertTreeMenuData(data, 0);
    // 处理上级节点查询
    findNodeList();
  };
  // 上级节点查询
  const findNodeList = async () => {
    const data = await getMenuList();
    formTreeSource.value = [
      {
        id: 0,
        pid: null,
        name: '根节点',
        children: convertTreeMenuData(data, 0),
      },
    ];
  };
  const rowSelection = ref({
    checkStrictly: false,
    onChange: (selectedRowKeys, selectedRows) => {
      console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
    },
    onSelect: (record, selected, selectedRows) => {
      console.log(record, selected, selectedRows);
    },
    onSelectAll: (selected, selectedRows, changeRows) => {
      console.log(selected, selectedRows, changeRows);
    },
  });

  // 检索
  const reset = () => {
    formState.name = '';
    delete formState.active;
  };
  // 删除
  const delMenu = async (id: number) => {
    console.log('id+++++++', id);

    await deleteMenu({ id: id });
    message.success('菜单删除成功');
    findList();
  };

  // 弹窗
  const visible = ref(false);
  const addMenu = () => {
    drawTit.value = '新建菜单';
    visible.value = true;
  };
  const editMenu = async (id) => {
    const data = await getMenuDetail({ id });
    formObj.value = {
      ...data,
      parentMenu: data.pid,
    };
    drawTit.value = '编辑菜单';
    visible.value = true;
  };
  const handlerClose = () => {
    formObj.value = {};
    visible.value = false;
  };
  // 找寻节点对应的那条数据
  const findNodeByName = (tree, name) => {
    for (const item of tree) {
      if (item.name === name) {
        return item;
      }
      // 如果找不到但是他有字节点
      if (item.children && item.children.length > 0) {
        const result = findNodeByName(item.children, name);
        if (result) {
          return result;
        }
      }
    }
    return null;
  };
  // 判断所有子菜单全部关闭后,主菜单才能关闭
  const checkAllChildrenMenuDisabled = (item, active) => {
    // 如果当前节点没有子节点，直接返回 true（因为没有子节点需要检查）
    if (!item.children || item.children.length === 0) {
      return true;
    }
    let isBol = true;
    for (const child of item.children) {
      if (child.active != active) {
        isBol = false;
      }
      // 递归检查子节点的子节点，如果任何一个子节点不满足条件，则 isBol 应为 false
      if (!checkAllChildrenMenuDisabled(child, active)) {
        isBol = false;
      }
    }
    return isBol;
  };
  const btnOk = async () => {
    console.log(formObj.value);
    formObj.value = {
      ...formObj.value,
      pid: formObj.value.parentMenu,
    };
    delete formObj.value.parentMenu;
    if (formObj.value.id) {
      // 编辑
      if (formObj.value.active == 0) {
        // 找寻节点对应的那条数据
        const menuItem = findNodeByName(formTreeSource.value, formObj.value.name);
        if (menuItem.children.length > 0) {
          // 判断所有子菜单全部关闭后,主菜单才能关闭
          const isBol = checkAllChildrenMenuDisabled(menuItem, formObj.value.active);
          if (!isBol) {
            return message.error('请先关闭子菜单');
          }
        }
      }
      await updateMenu(formObj.value);
      message.success('更新菜单成功');
    } else {
      // 新增
      await createMenu(formObj.value);
      message.success('创建菜单成功');
    }
    handlerClose();
    findList();
  };
</script>

<style scoped lang="less">
  .wrapper {
    padding: 20px;

    .search {
      margin-bottom: 20px;
      padding: 20px;
      background-color: #fff;
    }

    .tableWrapeer {
      padding: 20px;
      background-color: #fff;

      .btnUnion {
        margin-bottom: 10px;
      }
    }
  }

  .custom-class {
    .formFlex {
      display: flex !important;
    }

    .formFlex > *:last-child {
      margin-left: 20px;
    }
  }
</style>
